package api

import (
	"gitee.com/gopher2011/gin"
	jwt "gitee.com/gopher2011/gin-jwt"
	"time"
)

var identityKey = "id"

// 登陆请求参数
type Login struct {
	Username string `form:"username" json:"username" v:"required"`
	Password string `form:"password" json:"password" v:"required"`
}

// 被token保护的 User 信息
type User struct {
	UserName  string
	FirstName string
	LastName  string
}

// 测试用例:helloHandler
func helloHandler(c *gin.Context) {
	claims := jwt.ExtractClaims(c)
	user, _ := c.Get(identityKey)
	c.JSON(200, gin.H{
		"userID":   claims[identityKey],
		"userName": user.(*User).UserName,
		"text":     "Hello World.",
	})
}

func Jwt() (*jwt.JWTMiddleware, error) {
	auth, err := jwt.New(&jwt.JWTMiddleware{
		Realm:       "test zone",
		Key:         []byte("secret key"),
		Timeout:     time.Hour,
		MaxRefresh:  time.Hour,
		IdentityKey: identityKey,
		PayloadFunc: func(data interface{}) jwt.MapClaims {
			if v, ok := data.(*User); ok {
				return jwt.MapClaims{
					identityKey: v.UserName,
				}
			}
			return jwt.MapClaims{}
		},

		IdentityHandler: func(c *gin.Context) interface{} {
			claims := jwt.ExtractClaims(c)
			return &User{
				UserName: claims[identityKey].(string),
			}
		},

		AuthFunc: func(c *gin.Context) (interface{}, error) {
			var l Login
			if err := c.Parse(&l); err != nil {
				return "", jwt.ErrMissingLoginValues
			}
			userID := l.Username
			password := l.Password

			if (userID == "admin" && password == "admin") || (userID == "test" && password == "test") {
				return &User{
					UserName: userID,
				}, nil
			}
			return nil, jwt.ErrFailedAuthentication
		},

		AuthAfter: func(data interface{}, c *gin.Context) bool {
			if v, ok := data.(*User); ok && v.UserName == "admin" {
				return true
			}

			return false
		},

		UnAuthFunc: func(c *gin.Context, code int, message string) {
			c.JSON(code, gin.H{
				"code":    code,
				"message": message,
			})
		},
	})
	if err != nil {
		return nil, err
	}
	return auth, nil
}
